using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Authorization;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using TerritoryGame.Infrastructure.Data;
using TerritoryGame.Domain.Entities;

namespace TerritoryGame.API.Controllers;

[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
    private readonly TerritoryGameDbContext _db;
    private readonly IConfiguration _config;

    public AuthController(TerritoryGameDbContext db, IConfiguration config)
    {
        _db = db;
        _config = config;
    }

    public record RegisterRequest(string Username, string Email, string Password);
    public record LoginRequest(string UsernameOrEmail, string Password);

    [HttpPost("register")]
    [AllowAnonymous]
    public async Task<IActionResult> Register([FromBody] RegisterRequest req)
    {
        if (string.IsNullOrWhiteSpace(req.Username) || string.IsNullOrWhiteSpace(req.Email) || string.IsNullOrWhiteSpace(req.Password))
            return BadRequest("缺少必填字段");

        if (await _db.Users.AnyAsync(u => u.Username == req.Username))
            return Conflict("用户名已存在");
        if (await _db.Users.AnyAsync(u => u.Email == req.Email))
            return Conflict("邮箱已存在");

        var hash = BCrypt.Net.BCrypt.HashPassword(req.Password);
        var user = new User
        {
            Id = Guid.NewGuid(),
            Username = req.Username.Trim(),
            Email = req.Email.Trim().ToLowerInvariant(),
            PasswordHash = hash,
            CreatedAt = DateTime.UtcNow
        };
        _db.Users.Add(user);
        await _db.SaveChangesAsync();
        return Ok(new { user.Id, user.Username, user.Email });
    }

    [HttpPost("login")]
    [AllowAnonymous]
    public async Task<IActionResult> Login([FromBody] LoginRequest req)
    {
        if (string.IsNullOrWhiteSpace(req.UsernameOrEmail) || string.IsNullOrWhiteSpace(req.Password))
            return BadRequest("缺少必填字段");

        var key = _config["Jwt:Key"] ?? "Dev_Temp_Key_Change_Me_This_Is_At_Least_64_Characters_Long_0123456789";
        var issuer = _config["Jwt:Issuer"] ?? "TerritoryGame";

        var ue = req.UsernameOrEmail.Trim();
        var user = await _db.Users.FirstOrDefaultAsync(u => u.Username == ue || u.Email == ue);
        if (user == null) return Unauthorized("用户不存在");

        if (!BCrypt.Net.BCrypt.Verify(req.Password, user.PasswordHash))
            return Unauthorized("密码错误");

        var claims = new[]
        {
            new Claim(JwtRegisteredClaimNames.Sub, user.Id.ToString()),
            new Claim(ClaimTypes.Name, user.Username)
        };
        var creds = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key)), SecurityAlgorithms.HmacSha256);
        var token = new JwtSecurityToken(
            issuer: issuer,
            audience: null,
            claims: claims,
            expires: DateTime.UtcNow.AddDays(7),
            signingCredentials: creds
        );
        var jwt = new JwtSecurityTokenHandler().WriteToken(token);
        return Ok(new { token = jwt, user = new { user.Id, user.Username, user.Email } });
    }
}


